
#include <QDebug>
#include <QMdiSubWindow>
#include <QFileDialog>
#include <QCloseEvent>
#include <QMdiArea>
#include <QString>
#include <QSettings>
#include <QAction>
#include <QMenuBar>
#include <Qsci/qsciscintilla.h>
#include <Qsci/qscilexercpp.h>
#include <QTabBar>

#include "slanEdit.h"
#include "slanProjectFileDock.h"
#include "slanNewProjectWidget.h"


SlanEdit::SlanEdit(QWidget *parent)
    : QMainWindow(parent)
{
    createMdiWidgets();//这个需要在开始的时候初始化Mdi
    createWidgets();
    createMenuBar();   
    createStatusBar();
    createDockWdiget();

    setCentralWidget(mdiArea);

    readSettings();

    setWindowTitle(tr("SlanEditor"));
}

void SlanEdit::createWidgets()
{
    insertFileAction();
    insertEditAction();
    insertWindowAction();
    insertHelpAction();

}

void SlanEdit::createMenuBar()
{

    insertFileMenu();
    insertEditMenu();
    insertWindowMenu();
    insertHelpMenu();
}

void SlanEdit::createToolBar()
{

}

void SlanEdit::createStatusBar()
{

}

void SlanEdit::createMdiWidgets()
{
    mdiArea = new QMdiArea(this);
//    mdiArea->AreaOptions(QMdiArea::DontMaximizeSubWindowOnActivation);//
    mdiArea->setViewMode(QMdiArea::TabbedView);
    mdiArea->setTabShape(QTabWidget::Triangular);
    mdiArea->setTabsMovable(true);
    mdiArea->setTabsClosable(true);
    mdiArea->setTabPosition(QTabWidget::North);
    mdiArea->setOption(QMdiArea::DontMaximizeSubWindowOnActivation);
    mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    mdiArea->findChild<QTabBar*>()->setExpanding(false);
    mdiArea->showMaximized();
    connect(mdiArea, &QMdiArea::subWindowActivated,
            this, &SlanEdit::updateActions);

}

void SlanEdit::createDockWdiget()
{
//    setDockOptions(SlanEdit::ForceTabbedDocks);
    projectFileDockWidget = new SlanProjectFileDock(tr("项目"), this);
    projectFileDockWidget->setAllowedAreas(Qt::AllDockWidgetAreas);
    projectFileDockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
    projectFileDockWidget->setFloating(false);
    projectFileDockWidget->setVisible(true);
    addDockWidget(Qt::LeftDockWidgetArea, projectFileDockWidget);//向主窗口添加dockwidget，并且设置停靠位置

//    connect(projectFileDockWidget, &SlanProjectFileDock::createdFile, this,
//            static_cast< void (SlanEdit::*)(const QString &) >(&SlanEdit::slotOpenFile) );

    connect(projectFileDockWidget, &SlanProjectFileDock::createdFile, this,
            static_cast<void (SlanEdit::*)(const QString &)>(&SlanEdit::slotOpenFile));


    dirFileDockWidget = new SlanDirFileDock(tr("目录"), this);
    dirFileDockWidget->setAllowedAreas(Qt::AllDockWidgetAreas);
    dirFileDockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
    dirFileDockWidget->setFloating(false);
    dirFileDockWidget->setVisible(true);
    addDockWidget(Qt::LeftDockWidgetArea, projectFileDockWidget);//向主窗口添加dockwidget，并且设置停靠位置

    tabifyDockWidget(projectFileDockWidget, dirFileDockWidget);//设置两个dock堆叠
    projectFileDockWidget->show();
    projectFileDockWidget->raise();//选中该dock



}

void SlanEdit::readSettings()
{
    QSettings settings("Slanl", "SlanEditor");
    QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
    QSize size = settings.value("size", QSize(400, 400)).toSize();
    resize(size);
    move(pos);
}

void SlanEdit::writeSettings()
{
    QSettings settings("Slanl", "SlanEditor");
    settings.setValue("pos", pos());
    settings.setValue("size", size());
}

void SlanEdit::insertFileAction()
{
    newFileAct = new QAction(QIcon(":/images/new.png"), tr("新建(&T)"), this);
    newFileAct->setShortcut(QKeySequence::New);
    newFileAct->setStatusTip(tr("新建"));
    connect(newFileAct, &QAction::triggered, this, &SlanEdit::slotNewFile);

    openFileAct = new QAction(QIcon(":/images/open.png"), tr("打开文件(&T)"), this);
    openFileAct->setShortcut(QKeySequence::Open);
    openFileAct->setStatusTip(tr("打开文件"));
    connect(openFileAct, &QAction::triggered, this,
            static_cast<void (SlanEdit::*)()>(&SlanEdit::slotOpenFile));

    newProjectAct = new QAction(tr("创建项目(&P)"), this);
    newProjectAct->setShortcut(QKeySequence("Ctrl+Shift+N"));
    newProjectAct->setStatusTip(tr("创建项目"));
    connect(newProjectAct, &QAction::triggered, this, &SlanEdit::slotNewProjectFile);

    openProjectAct = new QAction(tr("打开项目(&P)"), this);
    openProjectAct->setShortcut(QKeySequence("Ctrl+Shift+P"));
    openProjectAct->setStatusTip(tr("打开项目"));
    connect(openProjectAct, &QAction::triggered, this, &SlanEdit::slotOpenProjectFile);

    saveFileAct = new QAction(QIcon(":/images/save.png"), tr("保存文件(&S)"), this);
    saveFileAct->setShortcut(QKeySequence::Save);
    saveFileAct->setStatusTip(tr("保存文件"));
    connect(saveFileAct, &QAction::triggered, this, &SlanEdit::slotSaveFile);

    saveAsFileAct = new QAction(QIcon(":/images/asave.png"), tr("另存为(&A)"), this);
    saveAsFileAct->setShortcut(QKeySequence::SaveAs);
    saveAsFileAct->setStatusTip(tr("另存为"));
    connect(saveAsFileAct, &QAction::triggered, this, &SlanEdit::slotSaveAsFile);

    closeFileAct = new QAction(tr("关闭文件"), this);
    closeFileAct->setShortcut(QKeySequence::Close);
    closeFileAct->setStatusTip(tr("关闭当前文件"));
    connect(closeFileAct, &QAction::triggered, mdiArea, &QMdiArea::closeActiveSubWindow);

    closeAllFileAct = new QAction(tr("关闭所有文件"), this);
//    closeAllFileAct->setShortcut(QKeySequence::);
    closeAllFileAct->setStatusTip(tr("关闭所有文件"));
    connect(closeAllFileAct, &QAction::triggered, mdiArea, &QMdiArea::closeAllSubWindows);

    exitSoftWareAct = new QAction(tr("退出"), this);
    exitSoftWareAct->setShortcut(QKeySequence::Quit);
    exitSoftWareAct->setStatusTip(tr("退出"));
    connect(exitSoftWareAct, &QAction::triggered, this, &SlanEdit::close);


}

void SlanEdit::insertEditAction()
{
    undoAct = new QAction(QIcon(":/images/undo.png"),tr("撤销"), this);
    undoAct->setShortcut(QKeySequence::Redo);
    undoAct->setStatusTip(tr("撤销这次修改"));
    undoAct->setEnabled(false);
    connect(undoAct, &QAction::triggered, this, &SlanEdit::slotUndo);

    redoAct = new QAction(QIcon(":/images/redo.png"),tr("恢复"), this);
    redoAct->setShortcut(QKeySequence::Undo);
    redoAct->setStatusTip(tr("恢复上一次操作"));
    redoAct->setEnabled(false);
    connect(redoAct, &QAction::triggered, this, &SlanEdit::slotRedo);


    cutAct = new QAction(QIcon(":/images/cut.png"),tr("剪切"), this);
    cutAct->setShortcut(QKeySequence::Cut);
    cutAct->setStatusTip(tr("剪切当前选中内容到剪切板"));
    cutAct->setEnabled(false);
    connect(cutAct, &QAction::triggered, this, &SlanEdit::slotCut);

    copyAct = new QAction(QIcon(":/images/copy.png"),tr("复制"), this);
    copyAct->setShortcut(QKeySequence::Copy);
    copyAct->setStatusTip(tr("复制当前选中内容到剪切板"));
    copyAct->setEnabled(false);
    connect(copyAct, &QAction::triggered, this, &SlanEdit::slotCopy);

    pasteAct = new QAction(QIcon(":/images/paste.png"),tr("粘贴"), this);
    pasteAct->setShortcut(QKeySequence::Paste);
    copyAct->setStatusTip(tr("复制当前选中内容到剪切板"));
    connect(pasteAct, &QAction::triggered, this, &SlanEdit::slotPaste);

}

void SlanEdit::insertWindowAction()
{

}

void SlanEdit::insertHelpAction()
{
}

void SlanEdit::insertFileMenu()
{
    fileMenu = menuBar()->addMenu(tr("文件(&F)"));
    fileMenu->addAction(newFileAct);
    fileMenu->addAction(openFileAct);

    projectMenu = fileMenu->addMenu(tr("项目"));

    fileMenu->addSeparator();
    fileMenu->addAction(saveFileAct);
    fileMenu->addAction(saveAsFileAct);
    fileMenu->addSeparator();
    fileMenu->addAction(closeFileAct);
    fileMenu->addAction(closeAllFileAct);
    fileMenu->addSeparator();
    fileMenu->addAction(exitSoftWareAct);

    projectMenu->addAction(newProjectAct);
    projectMenu->addAction(openProjectAct);



}

void SlanEdit::insertEditMenu()
{
    editMenu = menuBar()->addMenu(tr("编辑(&E)"));
    editMenu->addAction(undoAct);
    editMenu->addAction(redoAct);
    editMenu->addSeparator();
    editMenu->addAction(cutAct);
    editMenu->addAction(copyAct);
    editMenu->addAction(pasteAct);

}

void SlanEdit::insertWindowMenu()
{
    WindowMenu = menuBar()->addMenu(tr("窗口(&W)"));
}

void SlanEdit::insertHelpMenu()
{
    helpMenu = menuBar()->addMenu(tr("帮助(&H)"));

}

SlanEditWidget *SlanEdit::createSlanEditWidget()
{
    SlanEditWidget *child = new SlanEditWidget(this);
    mdiArea->addSubWindow(child);
    child->showMaximized();//默认最大化

    //对剪切复制动作进行设置
#ifndef QT_NO_CLIPBOARD
    connect(child, &SlanEditWidget::copyAvailable, cutAct, &QAction::setEnabled);
    connect(child, &SlanEditWidget::copyAvailable, copyAct, &QAction::setEnabled);
#endif
    connect(child, &SlanEditWidget::undoAvailable, undoAct, &QAction::setEnabled);
    connect(child, &SlanEditWidget::redoAvailable, redoAct, &QAction::setEnabled);


    return child;
}

//void SlanEdit::addSlanEditerWidget(SlanEditWidget *widget)
//{
//    /*QMdiSubWindow* win = */mdiArea->addSubWindow(widget);

////    m_windowMenu->addAction(widget->windowMenuAction());

////    m_actionGroup->addAction(widget->windowMenuAction());

////    if (!m_wsvAction->isChecked())
////        widget->setWhitespaceVisibility(
////        QsciScintilla::WhitespaceVisibility::WsInvisible);

////    win->show();
//}

void SlanEdit::slotSaveFile()
{
    SlanEditWidget* widget = activeSlanEditWidget();
    if (widget != NULL)
        widget->save();
}

void SlanEdit::slotSaveAsFile()
{
    SlanEditWidget* widget = activeSlanEditWidget();
    if (widget != NULL)
        widget->saveAs();
}

void SlanEdit::slotOpenFile()
{
    qDebug() << "slotOpenFile";
    QStringList fileNameList = QFileDialog::getOpenFileNames(this,tr("打开"), ".");
    foreach ( const QString fileName, fileNameList )
    {
        qDebug() <<fileName;
        SlanEditWidget * newEditWidget = createSlanEditWidget();
        newEditWidget->openFile(fileName);
        newEditWidget->show();
    }
}

void SlanEdit::slotOpenFile(const QString & fileName)
{
    SlanEditWidget * newEditWidget = createSlanEditWidget();
    newEditWidget->openFile(fileName);
    newEditWidget->show();

}

void SlanEdit::slotNewProjectFile()
{
    QString name;
    QString dirPath;
    SlanNewProjectWidget * proWidget = new SlanNewProjectWidget(this);
    proWidget->exec();

    name = proWidget->getName();
    dirPath = proWidget->getDirPath();
    if ( !proWidget->getName().isEmpty() )
        projectFileDockWidget->createProjectTree(name, dirPath);


}

void SlanEdit::slotOpenProjectFile()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("打开"), ".",
                                                    tr("SlanEditor Project file(*.sle)\n"));
    if ( fileName.isEmpty() )
        return;



}

void SlanEdit::slotNewFile()
{
    SlanEditWidget * newEditWidget = createSlanEditWidget();
    newEditWidget->newFile();
    newEditWidget->show();
}

//void SlanEdit::slotCloseFile()
//{
//    qDebug() << "slotCloseFile";
//}

//void SlanEdit::slotCloseAllFile()
//{
//    qDebug() << "slotCloseAllFile";
//}

//void SlanEdit::slotExit()
//{
//    qDebug() << "slotExit";
//}

void SlanEdit::slotUndo()
{
    SlanEditWidget* widget = activeSlanEditWidget();
    if (widget != NULL)
        widget->undo();
}

void SlanEdit::slotRedo()
{
    SlanEditWidget* widget = activeSlanEditWidget();
    if (widget != NULL)
        widget->redo();
}


void SlanEdit::slotCut()
{
    SlanEditWidget* widget = activeSlanEditWidget();
    if (widget != NULL)
        widget->cut();
}

void SlanEdit::slotCopy()
{
    SlanEditWidget* widget = activeSlanEditWidget();
    if (widget != NULL)
        widget->copy();
}

void SlanEdit::slotPaste()
{
    SlanEditWidget* widget = activeSlanEditWidget();
    if (widget != NULL)
        widget->paste();
}


void SlanEdit::updateActions()
{
    SlanEditWidget* widget = activeSlanEditWidget();

    bool hasEditer = (widget != NULL);

    bool hasSelection = (widget != NULL &&
        widget->hasSelectedText());

    saveFileAct->setEnabled(hasEditer);
    saveAsFileAct->setEnabled(hasEditer);

    redoAct->setEnabled((hasEditer && widget->isRedoAvailable()));
    undoAct->setEnabled((hasEditer && widget->isUndoAvailable()));

    cutAct->setEnabled(hasSelection);
    copyAct->setEnabled(hasSelection);
    pasteAct->setEnabled(hasEditer);

    closeFileAct->setEnabled(hasEditer);
    closeAllFileAct->setEnabled(hasEditer);
//    m_tileAction->setEnabled(hasEditer);
//    m_cascadeAction->setEnabled(hasEditer);
//    m_nextAction->setEnabled(hasEditer);
//    m_prevAction->setEnabled(hasEditer);

    if (widget != NULL)
        widget->windowMenuAction()->setChecked(true);
}

SlanEditWidget *SlanEdit::activeSlanEditWidget() const
{
    QMdiSubWindow* win = mdiArea->activeSubWindow();

    return (win != NULL) ? qobject_cast<SlanEditWidget*>(win->widget()) : NULL;
}

void SlanEdit::closeEvent(QCloseEvent *event)
{
    mdiArea->closeAllSubWindows();
    writeSettings();
    //if (mdiArea->currentSubWindow())
    if (!mdiArea->subWindowList().isEmpty())
        event->ignore();
    else
        event->accept();
}
